#include "DL_Mode_Handler.h"
#include <rtthread.h>   //在MH中调用了信号量来进行同步
#include "List.h"

//归属不同速度的Port列表

plist* PortsOfSpeed1 ;
plist* PortsOfSpeed2 ;
plist* PortsOfSpeed3 ;


//Mode handler状态机状态数据
DL_ModeHandler_STATE_TYPE DL_Mode_CurrentState[PORT_NUM]; 
//Mode Handlder中建立COM通讯重试次数
uint8_t DL_Mode_Retry[PORT_NUM]; 







/********************状态动作**********************************/
 
 void Action_WURQ_5(uint8_t Port){
    PL_Wake_Up(Port);
    Set_Timer_of_Tdmt(Port,138);//定时138us=32Tbit
 }

 void Action_ComRequestCOM3_6(uint8_t Port){
     Event_MH_Conf_COMx(Port);
    //启动定时器等待Tdmt
    Set_Timer_of_Tdmt(Port,833); //定时833us=32Tbit
 }

 void Action_ComRequestCOM2_7(uint8_t Port){
     Event_MH_Conf_COMx(Port);
     //启动定时器等待Tdmt
    Set_Timer_of_Tdmt(Port,6666);  //定时6666us=32Tbit

 }
 
void Action_ComRequestCOM1_8(uint8_t Port){
    Event_MH_Conf_COMx(Port);
    //启动定时器等待Tdmt
    Set_Timer_of_Tdmt(Port,6666); //

}



/*********************辅助函数*********************************/
 //每次进行DL_SetMode后调用此函数，设置MC结构
void MY_Update_MC_Struct(uint8_t Port){
    
    switch (MC_Struct[Port].M_sequenceType)
    {
    case TYPE_0:{
         MC_Struct[Port].OD=MC_Struct[Port].MC+2;
			    
			   MC_Struct[Port].CKS=MC_Struct[Port].MC+3;
			    MC_Struct[Port].PDin=NULL;
         MC_Struct[Port].PDout=NULL;
			  
			  
         
        break;
    }
    case TYPE_1_1_And_TYPE_1_2:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=MC_Struct[Port].MC+2;
        
        MC_Struct[Port].PDout=MC_Struct[Port].MC+2;
        MC_Struct[Port].OD=MC_Struct[Port].MC+2;

        
       break; 
    }
   
    case TYPE_1_V:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=NULL;
        MC_Struct[Port].PDout=NULL;
        break;
    }

    case TYPE_2_1:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=MC_Struct[Port].MC+3;
        MC_Struct[Port].PDout=NULL;
        break;
    }
    case TYPE_2_2:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=MC_Struct[Port].MC+3;
        MC_Struct[Port].PDout=NULL;
        break;
    }
    case TYPE_2_3:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+3;
        MC_Struct[Port].PDout=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=NULL;
        break;
    }   
    case TYPE_2_4:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+4;
        MC_Struct[Port].PDout=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=NULL;
        break;
    }

    case TYPE_2_5:{
        MC_Struct[Port].OD=MC_Struct[Port].MC+3;
        MC_Struct[Port].PDout=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=MC_Struct[Port].MC+4;
      
        break;
    }
    case TYPE_2_V:{
         
        MC_Struct[Port].OD=MC_Struct[Port].MC+2+MC_Struct[Port].PDOutputLength;
        MC_Struct[Port].PDout=MC_Struct[Port].MC+2;
        MC_Struct[Port].PDin=MC_Struct[Port].MC+2+MC_Struct[Port].PDOutputLength+MC_Struct[Port].ODLength;
     
        break;
    }

    default:
        break;
    }

}




//初始化DL状态
void DL_Mode_Init(void){
   
   for(uint8_t i=0;i<PORT_NUM;i++){
       //初始化Mode handler
       DL_Mode_CurrentState[i]=Idle_0;
  
   }
	 //不同速度的Port列表,在Operate—Thread线程中，将根据不同速度队列运行
	 PortsOfSpeed1 =(plist *)rt_malloc(sizeof(plist));
	 PortsOfSpeed1 =(plist *)rt_malloc(sizeof(plist));
	 PortsOfSpeed1 =(plist *)rt_malloc(sizeof(plist));
	 List_Init(PortsOfSpeed1);
	 List_Init(PortsOfSpeed2);
	 List_Init(PortsOfSpeed3);
	 
}
/**********************输出Event*********************/
//通知SM当前处于PreOperate状态
 void Event_DL_Mode_PEOPERATE(uint8_t Port){
	     //待更新
 }


/**********************输入Event******************/

void Event_DL_SetMode_STARTUP(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==Idle_0){
      
       DL_Mode_CurrentState[Port]=EstablishCom_1;
			 DL_Mode_T1(Port);
       return;
       
       
    }
    if(DL_Mode_CurrentState[Port]==PreOperate_3){
       
       DL_Mode_CurrentState[Port]=Mode_Startup_2;
			DL_Mode_T7(Port);
       return ;
    } 
    
     if(DL_Mode_CurrentState[Port]==Operate_4){
       
       DL_Mode_CurrentState[Port]=Mode_Startup_2;
			 DL_Mode_T12(Port);
       return  ;
    } 
}

void Event_DL_SetMode_PREOPERATE(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==Mode_Startup_2){
        
        DL_Mode_CurrentState[Port]=PreOperate_3;
			  DL_Mode_T6(Port);
        return ;
    } 
}

void Event_DL_SetMode_OPERATE(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==PreOperate_3){
       
        DL_Mode_CurrentState[Port]=Operate_4;
		  	 DL_Mode_T10(Port);
         
    }
    else if(DL_Mode_CurrentState[Port]==Mode_Startup_2){
        
        DL_Mode_CurrentState[Port]=Operate_4;
		  	DL_Mode_T11(Port);
         
    }else{
			
		}
		
		return;
}

void Event_DL_SetMode_INACTIVE(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==PreOperate_3){
        
        DL_Mode_CurrentState[Port]=Idle_0;
			  DL_Mode_T8(Port);
        return  ;
    } 
    
    if(DL_Mode_CurrentState[Port]==Operate_4){
        
        DL_Mode_CurrentState[Port]=Idle_0;
			  DL_Mode_T13(Port);
        return  ;
    } 
}

void Event_MHInfo_COMLOST(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==PreOperate_3){
       
       DL_Mode_CurrentState[Port]=Idle_0;
			 DL_Mode_T9(Port);
       
    }else if(DL_Mode_CurrentState[Port]==Operate_4){
      
      DL_Mode_CurrentState[Port]=Idle_0;
			 DL_Mode_T14(Port);
    }
}





//Retry=3事件,当建立通讯失败时调用
void Event_Retry_Equel_3(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==EstablishCom_1){
        
        DL_Mode_CurrentState[Port]=Idle_0;
        DL_Mode_T5(Port);
        
    }
     
}

/********************以下子状态EstablishCom的内部事件，已经由硬件实现****************************/
//Retry <3事件，内部事件
//当不用Max14819时候使用
void Event_tm_Tdwu(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==Retry_9){
        // DL_Mode_T19(Port);  空函数
        DL_Mode_CurrentState[Port]=WURQ_5;
       
    }
    
}
//当不用Max14819时候使用
void  Event_tm_Tdmt(uint8_t Port){
   if(DL_Mode_CurrentState[Port]==WURQ_5){
       
       DL_Mode_CurrentState[Port]=COM3_6;
		    DL_Mode_T15(Port);
       Action_ComRequestCOM3_6(Port); //状态动作
       return;
   }
   else if(DL_Mode_CurrentState[Port]==COM3_6){
      
      DL_Mode_CurrentState[Port]=COM2_7;
		  DL_Mode_T16(Port);
      Action_ComRequestCOM2_7(Port);
      return;
   }
    else if(DL_Mode_CurrentState[Port]==COM2_7){
      
      DL_Mode_CurrentState[Port]=COM1_8;
			DL_Mode_T17(Port);
      Action_ComRequestCOM1_8(Port);
      return;
   }
     else if(DL_Mode_CurrentState[Port]==COM1_8){
     
      DL_Mode_CurrentState[Port]=Retry_9;    
			  DL_Mode_T18(Port);
     
      return;
   }
   else{
       return ;
   }
}
/********************以上子状态EstablishCom的内部事件，已经由硬件实现**************/
void Event_Response_COM1_2_3(uint8_t Port){
    if(DL_Mode_CurrentState[Port]==EstablishCom_1){
        
        DL_Mode_CurrentState[Port]=Mode_Startup_2;
        DL_Mode_T2_3_4(Port);
        
    }

}

 

/*********************Mode_Handler状态机的转移动作******************/

void DL_Mode_T1(uint8_t Port){
   DL_Mode_Retry[Port]=0;
   //通知MH进入AwaitReply
   Event_MH_Conf_COMx(Port);  //通知MH准备建立通讯
   //Max14819中 EstCOM_bit置位，开始试图建立IO-link通信
    EstCOM(Port); //发送WURQ,以及发送MC读取字串,当通讯建立成功，引发中断，使得单片机读取Interrupt Register中的WURQInt位
                           //如果通讯建立成功，则引发Event_Response_OK和Event_Response_123事件
}

void DL_Mode_T2_3_4(uint8_t Port){
   Event_CH_Conf_ACTIVE(Port);
   //读取MAX寄存器，获得COM速度
	// COM_Speed_TYPE COM_Speed= Get_COM_Speed(Port);
      SM_COM_Speed[Port]=Get_COM_Speed(Port);  //DL_Mode.ind(COM)   //进入Startup之后获得COM速度
      SM_DL_STATE[Port]=STARTUP;             //DL_Mode.ind(Startup)
    //待更新，暂时停止此动作 Event_DL_Mode_STARTUP(Port);  //向SM发送事件
	 //
	
}
 

void DL_Mode_T5(uint8_t Port){
  //待更新，暂时停止此动作 SM_DL_STATE[Port]=INACATIVE;
}

void DL_Mode_T6(uint8_t Port){
 
   Event_OH_Conf_ACTIVE(Port);
   Event_IH_Conf_ACTIVE(Port);
   Event_EH_Conf_ACTIVE(Port);
   Event_MH_Conf_PREOPERATE(Port);
   //待更新，暂时停止此动作 SM_DL_STATE[Port]=PREOPERATE;
   Event_DL_Mode_PEOPERATE(Port);//向SM发送事件

}



void DL_Mode_T7(uint8_t Port){
   Event_MH_Conf_Startup(Port);
   Event_OH_Conf_INACTIVE(Port);
   Event_IH_Conf_INACTIVE(Port);
   Event_EH_Conf_INACTIVE(Port);
   //待更新，暂时停止此动作SM_DL_STATE[Port]=STARTUP;
   //待更新，暂时停止此动作 Event_DL_Mode_STARTUP(Port); ////向SM发送事件

}

void DL_Mode_T8(uint8_t Port){
    Event_CH_Conf_INACTIVE(Port);
    Event_MH_Conf_INACTIVE(Port);
    Event_OH_Conf_INACTIVE(Port);
    Event_IH_Conf_INACTIVE(Port);
    Event_EH_Conf_INACTIVE(Port);
    Event_PD_Conf_INACTIVE(Port);
    //待更新，暂时停止此动作SM_DL_STATE[Port]=INACATIVE;

}

void DL_Mode_T9(uint8_t Port){
     Event_CH_Conf_INACTIVE(Port);
    Event_MH_Conf_INACTIVE(Port);
    Event_OH_Conf_INACTIVE(Port);
    Event_IH_Conf_INACTIVE(Port);
    Event_EH_Conf_INACTIVE(Port);
    Event_PD_Conf_INACTIVE(Port);

    //待更新，暂时停止此动作 SM_DL_STATE[Port]=COMLOST;
    Event_DL_Mode_COMLOST(Port);
}

void DL_Mode_T10(uint8_t Port){
     M_sequnceTypeDef MType=MC_Struct[Port].M_sequenceType;
     if(MType==TYPE_2_1||MType==TYPE_2_2||MType==TYPE_2_3||MType==TYPE_2_4||MType==TYPE_2_5||MType==TYPE_2_V){
         Event_PD_Conf_SINGLE(Port);
     }

     if(MType==TYPE_1_1_And_TYPE_1_2){
         Event_PD_Conf_INTERLEAVE(Port);
     }
     Event_MH_Conf_OPERATE(Port);
     //待更新暂时停止此动作 SM_DL_STATE[Port]=OPERATE;
    //待更新，暂时停止此函数调用 Event_DL_Mode_OPERATE(Port);////向SM发送事件
}


void DL_Mode_T11(uint8_t Port){
    M_sequnceTypeDef MType=MC_Struct[Port].M_sequenceType;
     if(MType==TYPE_2_1||MType==TYPE_2_2||MType==TYPE_2_3||MType==TYPE_2_4||MType==TYPE_2_5||MType==TYPE_2_V){
         Event_PD_Conf_SINGLE(Port);
     }

     if(MType==TYPE_1_1_And_TYPE_1_2){
         Event_PD_Conf_INTERLEAVE(Port);
     }

     Event_OH_Conf_ACTIVE(Port);
     Event_IH_Conf_ACTIVE(Port);
     Event_EH_Conf_ACTIVE(Port);
     Event_MH_Conf_OPERATE(Port);
    //待更新，暂时停止此动作 SM_DL_STATE[Port]=OPERATE;
    //待更新，暂时停止此动作 Event_DL_Mode_OPERATE(Port);////向SM发送事件

}

void DL_Mode_T12(uint8_t Port){
   Event_MH_Conf_Startup(Port);
   Event_PD_Conf_INACTIVE(Port);
   Event_OH_Conf_INACTIVE(Port);
   Event_IH_Conf_INACTIVE(Port);
   Event_EH_Conf_INACTIVE(Port);
   //待更新，暂时停止此动作 SM_DL_STATE[Port]=STARTUP;
   //待更新，暂时停止此动作 Event_DL_Mode_STARTUP(Port);//向SM发送事件
}

void DL_Mode_T13(uint8_t Port){
    Event_CH_Conf_INACTIVE(Port);
    Event_MH_Conf_INACTIVE(Port);
    Event_OH_Conf_INACTIVE(Port);
    Event_IH_Conf_INACTIVE(Port);
    Event_EH_Conf_INACTIVE(Port);
    Event_PD_Conf_INACTIVE(Port);
   //待更新，暂时停止此动作 SM_DL_STATE[Port]=INACATIVE;
}

void DL_Mode_T14(uint8_t Port){
     Event_CH_Conf_INACTIVE(Port);
    Event_MH_Conf_INACTIVE(Port);
    Event_OH_Conf_INACTIVE(Port);
    Event_IH_Conf_INACTIVE(Port);
    Event_EH_Conf_INACTIVE(Port);
    Event_PD_Conf_INACTIVE(Port);
   //待更新，暂时停止此动作 SM_DL_STATE[Port]=COMLOST;
    Event_DL_Mode_COMLOST(Port);
}


/********************以下为没用MAX14819********************************/
//当不用Max14819时候使用
void DL_Mode_T15(uint8_t Port){
   //设置Port的传输速率为COM3模式(HAL_Driver)
   set_COM_Speed(Port,230400) ; 
   //comRequestCOM3_6 状态动作
   Action_ComRequestCOM3_6(Port);

}
//当不用Max14819时候使用
void DL_Mode_T16(uint8_t Port){
   //设置Port的传输速率为COM2模式(HAL_Driver)
   set_COM_Speed(Port,38400) ;
   //comRequestCOM2_7状态动作
   Action_ComRequestCOM2_7(Port);
}
//当不用Max14819时候使用
void DL_Mode_T17(uint8_t Port){
    //设置Port的传输速率为COM1模式(HAL_Driver)
   set_COM_Speed(Port,4800) ;
   //comRequestCOM1_8状态动作
   Action_ComRequestCOM1_8(Port);

}
//当不用Max14819时候使用
void DL_Mode_T18(uint8_t Port){
     DL_Mode_Retry[Port]++;

      if(DL_Mode_Retry[Port]==3){
          Event_Retry_Equel_3(Port); //Retry=3事件
      }else{
          //启动Tdwu定时器。在此定时器中断中，发送Event_tm_Tdwu
          Set_Timer_of_Tdwu(Port);
      }
}
//当不用Max14819时候使用
void DL_Mode_T19(uint8_t Port){

}



